package com.prueba.client.datosYlogica.vistas;

import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Set;
import java.util.TreeSet;

import com.prueba.client.datosYlogica.GestorStakeholders;
import com.prueba.client.datosYlogica.GestorVistas;
import com.prueba.client.extensiones.Par;
import com.prueba.compartido.Preferencia;
import com.prueba.compartido.Seccion;
import com.prueba.compartido.Stakeholder;
import com.prueba.compartido.Sugerencia;
import com.smartgwt.client.data.Record;

public class Vista {

	public static final String[] TIPOS_VISTAS = new String[] { "N/A", "DisenoDetallado",
			"Programacion" };

	protected static final int CANT_TIPOS = 3;

	protected static HashMap<String, Integer> tiposToInt;

	protected String nivelEnDocumento;

	public String getNivelEnDocumento() {
		return nivelEnDocumento;
	}

	public void setNivelEnDocumento(String nivelEnDocumento) {
		this.nivelEnDocumento = nivelEnDocumento;
	}

	public static int stringToTipo(String valor) {

		return tiposToInt.get(valor);
	}

	static {

		tiposToInt = new HashMap<String, Integer>();

		// Agrego todos los tipos y les asigno un int de valor:
		for (int i = 0; i < CANT_TIPOS; i++) {
			tiposToInt.put(TIPOS_VISTAS[i], i);

		}

		

	}

	protected String nombreVista;

	protected int tipo;

	public int getTipo() {
		return tipo;
	}

	public void setTipo(int tipo) {
		this.tipo = tipo;
	}

	public String tipoToString() {
		return tipoToString(this.tipo);
	}

	public static String tipoToString(int tipo) {

		if (tipo <= 0 && tipo >= CANT_TIPOS) {
			return "N/A";
		}

		else

		{
			return TIPOS_VISTAS[tipo];
		}

	}

	protected NivelVista niveles[];

	protected Set<Integer> seccionesFaltantes;

	public Vista(String nombreVista) {

		this.nombreVista = nombreVista;

		this.tipo = 0;

		this.niveles = new NivelVista[] {
				new NivelVista(nombreVista, Seccion.INT_NOTHING),
				new NivelVista(nombreVista, Seccion.INT_OVERVIEW),
				new NivelVista(nombreVista, Seccion.INT_SOMEDETAIL),
				new NivelVista(nombreVista, Seccion.INT_DETAILED) };
		this.seccionesFaltantes = tiposDeSecciones();
	}

	protected Set<Integer> tiposDeSecciones() {
		Set<Integer> aux = new TreeSet<Integer>();
		aux.add(Seccion.INT_Primary_presentation);
		aux.add(Seccion.INT_Element_catalog);
		aux.add(Seccion.INT_Context_Diagram);
		aux.add(Seccion.INT_Variability_Guide);
		aux.add(Seccion.INT_View_Rationale);
		return aux;
	}

	public String getNombreVista() {
		return nombreVista;
	}

	public int getCosto() {
		return niveles[0].getCosto() + niveles[1].getCosto()
				+ niveles[2].getCosto() + niveles[3].getCosto();
	}

	public int getNivelDeDetalle() {
		int nivel = Seccion.INT_NOTHING;
		while (nivel < Seccion.INT_DETAILED && this.niveles[nivel + 1].isDone())
			nivel++;
		return nivel;
	}

	public NivelVista getNivel(int nivel) {
		return this.niveles[nivel];
	}

	public void agregarSeccion(Seccion s) {

		switch (s.getTipo()) {
		case Seccion.INT_Primary_presentation:
			this.niveles[Seccion.INT_OVERVIEW].agregarSeccion(s);
			this.seccionesFaltantes.remove(Seccion.INT_Primary_presentation);
			break;
		case Seccion.INT_Element_catalog:
			this.niveles[Seccion.INT_SOMEDETAIL].agregarSeccion(s);
			this.seccionesFaltantes.remove(Seccion.INT_Element_catalog);
			break;
		case Seccion.INT_Context_Diagram:
			this.niveles[Seccion.INT_SOMEDETAIL].agregarSeccion(s);
			this.seccionesFaltantes.remove(Seccion.INT_Context_Diagram);
			break;
		case Seccion.INT_Variability_Guide:
			this.niveles[Seccion.INT_DETAILED].agregarSeccion(s);
			this.seccionesFaltantes.remove(Seccion.INT_Variability_Guide);
			break;
		case Seccion.INT_View_Rationale:
			this.niveles[Seccion.INT_DETAILED].agregarSeccion(s);
			this.seccionesFaltantes.remove(Seccion.INT_View_Rationale);
			break;
		}

		GestorVistas.getInstance().actualizarElemento(this.nombreVista,
				"costo", this.getCosto());
		GestorVistas.getInstance().actualizarElemento(this.nombreVista,
				"nivelDeDetalle", this.getNivelDeDetalle());
	}

	public void enlistarSugerencias(LinkedList<Sugerencia> sugerencias) {
		// sugerencias.add(new Sugerencia(this.nombreVista));
		for (Integer it:this.seccionesFaltantes) {
			sugerencias.add(new Sugerencia("Falta seccion de tipo "
					+ Seccion.tipoToString(it) + " en la vista "
					+ this.nombreVista));
		}

	}

	// public static Map<String,int[]> prefStakeholders;

	public void agregarPreferencia(Preferencia p) {

		System.out.println("Nueva preferencia:" + p.getNombreStakeholder()
				+ " " + p.getNombreVista() + " " + p.getNivelDeseado());

		Stakeholder s=GestorStakeholders.getInstance().getElemento(p.getNombreStakeholder());
		if(s!=null){
			int n = p.getNivelDeseado();
			this.niveles[n].agregarStakeholder(s);
		}
		/*Par<Record, Stakeholder> aux = Datos.stakeholders.get(p
				.getNombreStakeholder());
		if (aux != null) {
			int n = p.getNivelDeseado();
			Stakeholder s = aux.segundo;

			this.niveles[n].agregarStakeholder(s);
		}*/
		/*
		 * int nivelDeseado=p.getNivelDeseado(); Stakeholder
		 * s=Datos.stakeholders.get(p.getNombreStakeholder()).segundo;
		 * 
		 * if(nivelDeseado>Seccion.INT_NOTHING && s!=null){ int
		 * nivelDeDetalle=this.getNivelDeDetalle();
		 * this.niveles[p.getNivelDeseado()].agregarStakeholder(s);
		 * 
		 * int[] pref=prefStakeholders.get(p.getNombreStakeholder()); pref[1]++;
		 * if(nivelDeDetalle>=nivelDeseado){ pref[0]++;
		 * 
		 * }else{ if(s.getSatisfaccion().equals("SATISFECHO")) if(pref[0]>0)
		 * GestorStakeholders.actualizarStakeholder(p.getNombreStakeholder(),
		 * "ALGOSATISFECHO"); else
		 * GestorStakeholders.actualizarStakeholder(p.getNombreStakeholder(),
		 * "INSATISFECHO"); } }
		 */
	}

	public void actualizarPreferencia(Preferencia prefAnterior,
			int nuevoNivelDeseado) {

		System.out.println("Actualizada preferencia:"
				+ prefAnterior.getNombreStakeholder() + " "
				+ prefAnterior.getNombreVista() + " "
				+ prefAnterior.getNivelDeseado() + " " + nuevoNivelDeseado);

		Stakeholder s = GestorStakeholders.getInstance().getElemento(prefAnterior.getNombreStakeholder());
		/*Datos.stakeholders.get(prefAnterior
				.getNombreStakeholder()).segundo;*/
		int nivelDeseadoAnterior = prefAnterior.getNivelDeseado();

		this.niveles[nivelDeseadoAnterior].removerStakeholder(s);
		this.niveles[nuevoNivelDeseado].agregarStakeholder(s);

		// TODO Auto-generated method stub
		/*
		 * Stakeholder
		 * s=Datos.stakeholders.get(prefAnterior.getNombreStakeholder
		 * ()).segundo;
		 * 
		 * if(s!=null){
		 * 
		 * boolean estabaAntesSatisfecha; if(this.nivelDeDetalleAnterior)
		 * boolean estaAhoraSatisfecha;
		 * 
		 * int nivelDeDetalle=this.getNivelDeDetalle();
		 * 
		 * int
		 * 
		 * this.niveles[p.getNivelDeseado()].agregarStakeholder(s);
		 * 
		 * int[] pref=prefStakeholders.get(p.getNombreStakeholder()); pref[1]++;
		 * if(nivelDeDetalle>=nivelDeseado) pref[0]++; else
		 * if(s.getSatisfaccion().equals("SATISFECHO")) if(pref[0]>0)
		 * GestorStakeholders.actualizarStakeholder(p.getNombreStakeholder(),
		 * "ALGOSATISFECHO"); else
		 * GestorStakeholders.actualizarStakeholder(p.getNombreStakeholder(),
		 * "INSATISFECHO"); }
		 */
	}

	public void borrarPreferencia(Preferencia p) {
		Stakeholder s = GestorStakeholders.getInstance().getElemento(p.getNombreStakeholder());//Datos.stakeholders.get(p.getNombreStakeholder()).segundo;
		int n = p.getNivelDeseado();

		this.niveles[n].removerStakeholder(s);
	}

	public void borrarPreferencias() {
		for(int i=0;i<this.niveles.length;i++){
			niveles[i].removerStakeholders();
		}
	}

	public void borrarSecciones() {
		for(int i=0;i<this.niveles.length;i++){
			niveles[i].removerSecciones();
		}
	}
}